package comp6231.project.replica;

import comp6231.project.common.Constants;
import comp6231.project.common.ReplicaState;
import comp6231.project.replica.kelvin.ReplicaImpl;
import comp6231.project.replica.dimitri.RetailStoreServer;
import comp6231.project.replica.thomas.ReplicaStoreImpl;

public class ReplicaFactory {

	/**
	 * 
	 * @param replicaName for example M1, V2, T3. M/V/T means the store capital name, 
	 * 1/2/3 stand for different replica implementation.
	 * @return specific replica initialized
	 * @throws Exception
	 */
	public static Replica getReplica(String replicaName) throws Exception {
		
		Replica tempReplica = null;
		
		//code initialize from Dimitri
		if(replicaName.charAt(1)=='1')
		{
			if(replicaName.charAt(0)=='M')
				return new RetailStoreServer(Constants.REPLICA_ID_M1);
			else if(replicaName.charAt(0)=='T')
				return new RetailStoreServer(Constants.REPLICA_ID_T1);
			else if(replicaName.charAt(0)=='V')
				return new RetailStoreServer(Constants.REPLICA_ID_V1);
			else
				throw new Exception();
		}
		// code initialize from Kelvin
		else if(replicaName.charAt(1)=='2'){
			if(replicaName.charAt(0)=='M'){
				tempReplica =new ReplicaImpl(Constants.REPLICA_ID_M2);
				tempReplica.setReplicaId(Constants.REPLICA_ID_M2); 
				}
			else if(replicaName.charAt(0)=='T'){
				tempReplica = new ReplicaImpl(Constants.REPLICA_ID_T2);		
				tempReplica.setReplicaId(Constants.REPLICA_ID_T2);
			}
			else if(replicaName.charAt(0)=='V'){
				tempReplica = new ReplicaImpl(Constants.REPLICA_ID_V2);		
				tempReplica.setReplicaId(Constants.REPLICA_ID_V2);}
			else
				throw new Exception();

		} 
		//code initialize from thomas
		else if(replicaName.charAt(1)=='3'){
			if(replicaName.charAt(0)=='M'){
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_M3);
			}
			else if(replicaName.charAt(0)=='T')
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_T3);
			else if(replicaName.charAt(0)=='V')
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_V3);
			else
				throw new Exception();
		}
		
		else {
			throw new Exception();
		}
		
		return tempReplica;

	}

	public static Replica reCreateReplica(String replicaName, ReplicaState state) throws Exception{
		//code initialize from Dimitri
		Replica tempReplica = null;
		if(replicaName.charAt(1)=='1')
		{
			if(replicaName.charAt(0)=='M'){
				tempReplica = new RetailStoreServer(Constants.REPLICA_ID_M1);
				tempReplica.setReplicaState(state);
				}
			else if(replicaName.charAt(0)=='T'){
				tempReplica = new RetailStoreServer(Constants.REPLICA_ID_T1);
				tempReplica.setReplicaState(state);
				}
			else if(replicaName.charAt(0)=='V'){
				tempReplica = new RetailStoreServer(Constants.REPLICA_ID_V1);
				tempReplica.setReplicaState(state);
				}
			else
				throw new Exception();
		}
		// code initialize from Kelvin
		else if(replicaName.charAt(1)=='2'){
			if(replicaName.charAt(0)=='M'){
				tempReplica = new ReplicaImpl(Constants.REPLICA_ID_M2);
				tempReplica.setReplicaId(Constants.REPLICA_ID_M2);
				tempReplica.setReplicaState(state);
			}
			else if(replicaName.charAt(0)=='T'){
				tempReplica = new ReplicaImpl(Constants.REPLICA_ID_T2);
				tempReplica.setReplicaId(Constants.REPLICA_ID_T2);
				tempReplica.setReplicaState(state);
				}
			else if(replicaName.charAt(0)=='V'){
				tempReplica = new ReplicaImpl(Constants.REPLICA_ID_V2);
				tempReplica.setReplicaId(Constants.REPLICA_ID_V2);
				tempReplica.setReplicaState(state);
			}
			else
				throw new Exception();

		} 
		//code initialize from thomas
		else if(replicaName.charAt(1)=='3'){
			if(replicaName.charAt(0)=='M'){
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_M3);
				tempReplica.setReplicaState(state);
			}
			else if(replicaName.charAt(0)=='T'){
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_T3);
				tempReplica.setReplicaState(state);
			}
			else if(replicaName.charAt(0)=='V'){
				tempReplica =  new ReplicaStoreImpl(Constants.REPLICA_ID_V3);
				tempReplica.setReplicaState(state);
			}
			else
				throw new Exception();
		}
		
		else {
			throw new Exception();
		}
		
		return tempReplica;
	}
	
}
